# 1. 连续三日大单流入
# 2. 涨幅在 -2 ～ +4区间
# 3. 流通市值80亿以下
# 4. 获利5%止盈

from __future__ import division
from jqdata import *
import datetime
import tushare as ts

# 设置买入数量均摊仓位
# security 股票代码
def average_buy(context, security):
    # 买入股票
    log.info('买入股票');
    order_value(security, context.portfolio.cash);


# 卖出股票
# security 股票代码
def allon_sell(context, security):
    log.info('卖出股票');
    order_result = order_target_value(security, 0);

    if order_result is not None:
        # 因为不重复所以直接remove
        g.amount_main_and_turnover_top_list = [];
        log.info('卖出股票 %s 完成: ' % security);
        log.info('清除昨日持仓股票数据');

# 获取全部股票列表
def getAllSecurityList():
    return list(get_all_securities(['stock']).index);

# 前3日涨幅 -2 ～ +4 区间
def getNotHigh(context, security_list, count):
    result_security_list = [];
    # log.info('getNotHigh');

    # 获取前三日的数据
    for security in security_list:
        # log.info(security);
        security_df = get_price(security, count = 3, end_date = g.yester_dt, fields = ['high', 'low', 'pre_close', 'money'], frequency='daily');
        # log.info(security_df);

        lowRange_0 = (security_df['low'][0] / security_df['pre_close'][0]);
        highRange_0 = (security_df['high'][0] / security_df['pre_close'][0]);
        lowRange_1 = (security_df['low'][1] / security_df['pre_close'][1]);
        highRange_1 = (security_df['high'][1] / security_df['pre_close'][1]);
        lowRange_2 = (security_df['low'][2] / security_df['pre_close'][2]);
        highRange_2 = (security_df['high'][2] / security_df['pre_close'][2]);

        # # 判断是否停牌 成交量为0则判断为停牌
        if (security_df['money'][2] != 0):

            if (lowRange_0 >= 0.98 and highRange_0 <= 1.03 and lowRange_1 >= 0.98 and highRange_1 <= 1.03 and lowRange_2 >= 0.98 and highRange_2 <= 1.03):
                result_security_list.append(security);

    return result_security_list;

# 前3日大单连续流入
def getMainBuy(context, security_list, count):
    # log.info('getMainBuy');
    result_security_list = [];

    for security in security_list:
        g.money_flow_df = get_money_flow(security, end_date = g.yester_dt, fields = None, count = count);
        # log.info(security);
        # log.info(len(g.money_flow_df['net_amount_main']));

        if (len(g.money_flow_df['net_amount_main']) == 3 and g.money_flow_df['net_amount_main'][0] > 1000 and g.money_flow_df['net_amount_main'][1] > 1000 and g.money_flow_df['net_amount_main'][2] > 1000):
            result_security_list.append(security);
    #
    # log.info('前3日大单连续流入 %s ' % result_security_list);
    return result_security_list;

# 获取昨日流通市值小于80亿的股票
def getMiniMarket(security_list):
    # log.info('getMiniMarket');
    self_security_list = [];

    for security in security_list:
        queryResult = query(valuation).filter(valuation.code == security);
        df = get_fundamentals(queryResult, g.yester_dt);

        if (len(df.circulating_market_cap) > 0 and df.circulating_market_cap[0] < 80):
            self_security_list.append(security);

    return self_security_list;

# 初始化
def initialize(context):
    log.info('initialize');
    g.amount_main_and_turnover_top_list = [];

# 每日开盘
# 如果昨日没有持仓股票 则今日从新获取 今日备选买入列表
def before_trading_start(context):
    log.info('开盘');

    # 获取昨日时间
    g.yester_dt = context.current_dt + datetime.timedelta(days = -1);

    if (len(g.amount_main_and_turnover_top_list) == 0):
        log.info('昨日时间 %s ' % g.yester_dt);
        security_list = getAllSecurityList();
        mini_market_security_list = getMiniMarket(security_list);
        not_high_security_list = getNotHigh(context, mini_market_security_list, 3);
        main_buy_security_list = getMainBuy(context, not_high_security_list, 3);
        log.info('前3日涨幅 -2 ～ +4 区间 %s' % main_buy_security_list);
        g.amount_main_and_turnover_top_list = main_buy_security_list;
    else:
        log.info(g.amount_main_and_turnover_top_list);

# 每日收盘
# 如果 今日备选买入列表 中没有符合买入条件的股票 则清空 今日备选买入列表
def after_trading_end(context):
    log.info('收盘');

    if (len(g.amount_main_and_turnover_top_list) > 0):
        security = g.amount_main_and_turnover_top_list[0];

        if (context.portfolio.positions[security].avg_cost == 0):
            g.amount_main_and_turnover_top_list = [];

# 每分钟操作

# 每个时间段执行
def handle_data(context, data):

    # 获取当前时间数据
    current_data = get_current_data();

    if (len(g.amount_main_and_turnover_top_list) > 0):

        # for security in g.amount_main_and_turnover_top_list:

        security = g.amount_main_and_turnover_top_list[0];

        # 排除st
        if (current_data[security].is_st == False):
            g.last_df = history(1,'1d','close',[security]);

            # 得到当前价格
            price = data[security].close;

            # 获取这只股票昨天收盘价
            last_close = g.last_df[security][0];

            # 获取持仓成本
            avg_cost = context.portfolio.positions[security].avg_cost;

            # 获取当前价格
            price1 = context.portfolio.positions[security].price;

            if (price1 != 0 and avg_cost != 0):
                profit = price1 / avg_cost;
            else:
                profit = 0;

            # 涨幅2个点以下买入
            if (price != last_close and (price / last_close) < 1.02 and avg_cost == 0):
                log.info('%s 持仓成本 %s ' % (security, avg_cost));
                log.info('%s 昨日收盘价 %s' % (security, last_close));
                log.info('%s 当前价格 %s ' % (security, price));
                average_buy(context, security);

            # 收益1%止盈
            elif (price1 != 0 and avg_cost != 0 and profit >= 1.05):
                log.info('收益 %s 个点止盈' % ((profit - 1) * 100));
                allon_sell(context, security);
